// SHObserverManager.cpp: implementation of the SHObserverManager class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "SHObserverManager.h"
#include "UEEntityOperation.h"
#include <dbdict.h>
#include "Dictionary.h"
#include "Project.h"
#include "ProjectManager.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
using namespace DictionaryFacade;

SHObserverManager::SHObserverManager()
{

}

SHObserverManager::~SHObserverManager()
{

}

void SHObserverManager::SetManagerHandle(const AcDbHandle& handle)
{
	m_handle = handle;

	AcDbDictionary* pDic = OpenDictionary();
	ASSERT(pDic);

	Acad::ErrorStatus es = Acad::eOk;
	AcDbObject* pObj = NULL;
	AcDbDictionaryIterator* pIt = pDic->newIterator();
	for(; !pIt->done(); pIt->next())
	{
		es = pIt->getObject(pObj, AcDb::kForWrite);
		ASSERT(es == Acad::eOk);
		
		AcDbHandle handle;
		pObj->getAcDbHandle(handle);
		pObj->close();

		CString strName;
		strName = pIt->name();

		SHPoint pPt;
		pPt.Name(strName);
		pPt.SetDicHandle(handle);

	}
	delete pIt;
	pDic->close();
}

AcDbDictionary* SHObserverManager::OpenDictionary()
{
	AcDbObject* pObj = NULL;
	pObj = CUEEntityOperation::OpenObjectWrite(this->m_handle);
	ASSERT(pObj);

	if(pObj->isKindOf(AcDbDictionary::desc()))
		return static_cast<AcDbDictionary*>(pObj);
	return NULL;
}

BOOL SHObserverManager::HasSH(const CString& strName)
{
	AcDbDictionary* pDic = OpenDictionary();
	ASSERT(pDic);

	BOOL bResult = pDic->has(strName);
	pDic->close();
	return bResult;
}

SHPoint SHObserverManager::GetSHPoint(const CString& strName)
{
	SHPoint pPt;

	AcDbDictionary* pDic = OpenDictionary();
	ASSERT(pDic);

	BOOL bIsNew = FALSE;
	AcDbHandle handle;
	AcDbObjectId id;
	AcDbObject* pObj = NULL;
	Acad::ErrorStatus es = pDic->getAt(strName, pObj, AcDb::kForWrite);
	if(pObj == NULL)
	{
		pObj = new AcDbDictionary;
		pDic->setAt(strName, pObj, id);
		bIsNew = TRUE;
	}
	pDic->close();
	pObj->getAcDbHandle(handle);
	pObj->close();

	SupportHanger* pSH = NULL;
	if(GetProjectManager().CurProject()->
		GetSupportHangerManager().IsExist(strName))
	{
		pSH = GetProjectManager().CurProject()->
			GetSupportHangerManager().GetSupportHanger(strName);
	}
	pPt.Model(pSH);
	pPt.Name(strName);
	pPt.SetDicHandle(Dictionary(handle));
	if(!bIsNew && pSH != NULL)
		pSH->ModelMatrix(pPt.Matrix());
	
	return pPt;
}

void SHObserverManager::Update()
{
	Dictionary dic(m_handle);

	CStringArray strDelName;
	Project* pPrj = GetProjectManager().CurProject();

	AcDbDictionary* pDic = OpenDictionary();
	ASSERT(pDic);
	AcDbDictionaryIterator* pIt = pDic->newIterator();
	for(; !pIt->done(); pIt->next())
	{
		SupportHanger* pSH = pPrj->GetSupportHangerManager().
			GetSupportHanger(pIt->name());
		if(pSH == NULL)
		{
			strDelName.Add(pIt->name());
		}
		else
		{
			SHPoint pt;
			
			pt.Name(pIt->name());
			pt.Model(pSH);
			pt.SetDicHandle(Dictionary(pIt->objectId().handle()));
			pSH->ModelMatrix(pt.Matrix());
			pt.Update();
		}
	}
	delete pIt;

	for(int i = 0; i < strDelName.GetSize(); i++)
	{
		pDic->remove(strDelName.GetAt(i));
	}
	pDic->close();
}

void SHObserverManager::Remove(const CString& strName)
{
	SHPoint pPt = GetSHPoint(strName);
	pPt.Erase();

	AcDbDictionary* pDic = OpenDictionary();
	ASSERT(pDic);

	pDic->remove(strName);
	pDic->close();
}

SHObserverManager::Iterator* SHObserverManager::NewIterator()
{
	AcDbDictionary* pDic = OpenDictionary();
	ASSERT(pDic);

	Iterator* pIt = pDic->newIterator();
	pDic->close();

	return pIt;
}

SHPoint SHObserverManager::GetSHPoint(SupportHanger* pSH)
{
	ASSERT(pSH);

	SHPoint pt;
	pt = GetSHPoint(pSH->SupportHangerID());
	pt.Model(pSH);

	return pt;
}

void SHObserverManager::Remove(SupportHanger* pSH)
{
	SHPoint pPt = GetSHPoint(pSH);
	pPt.Erase();

	AcDbDictionary* pDic = OpenDictionary();
	ASSERT(pDic);

	pDic->remove(pSH->SupportHangerID());
	pDic->close();
}